﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using Common.DataTypes;
using System.Xml;
using System.IO;
using Common;

namespace SerchEngine
{
    public class ResultXMLParser
    {
        public string XmlToParse { get; set; }
        private Dictionary<string, int> DicProperties;

        public ResultXMLParser(string xml) {
            this.XmlToParse = xml;
            this.DicProperties = new Dictionary<string, int>();

            #region Load_Dic_properties
            this.DicProperties.Add("asin", Item.ASIN);
            this.DicProperties.Add("detailpageurl", Item.DETAILPAGEURL);
            this.DicProperties.Add("salesrank", Item.SALESRANK);
            this.DicProperties.Add("smallimage", Item.SMALLIMAGE);
            this.DicProperties.Add("mediumimage", Item.MEDIUMIMAGE);
            this.DicProperties.Add("largeimage", Item.LARGEIMAGE);
            this.DicProperties.Add("manufacturer", Item.MANUFACTURER);
            this.DicProperties.Add("listprice", Item.LISTPRICE);
            this.DicProperties.Add("packagedimensions", Item.PACKAGEDIMENSIONS);
            this.DicProperties.Add("label", Item.LABEL);
            this.DicProperties.Add("studio", Item.STUDIO);
            this.DicProperties.Add("binding", Item.BINDING);
            this.DicProperties.Add("ean", Item.EAN);
            this.DicProperties.Add("author", Item.AUTHOR);
            this.DicProperties.Add("isbn", Item.ISBN);
            this.DicProperties.Add("publicationdate", Item.PUBLICATIONDATE);
            this.DicProperties.Add("publisher", Item.PUBLISHER);
            this.DicProperties.Add("releasedate", Item.RELEASEDATE);
            this.DicProperties.Add("title", Item.TITLE);
            #endregion
        }

        public List<Item> Parse() {
            List<Item> lista_resultado = new List<Item>();
            Book book = null;
            int property_to_assign = Item.INVALID;
            int inner_property_to_assign = Item.INVALID;
            string xml_node_name;
            Object inner_value = null;

            // Start to parse the xml
            XmlReader xml_reader = XmlReader.Create(new StringReader(this.XmlToParse));


            string prueba = xml_reader.GetAttribute("URL");


            while (xml_reader.Read()) {
                switch (xml_reader.NodeType) { 
                    
                    // Found open tag - <Element>
                    case XmlNodeType.Element:
                        xml_node_name = xml_reader.Name.ToLower();
                        if (xml_node_name.Equals("item")) {
                            book = new Book();
                            lista_resultado.Add(book);
                        }
                        else if (this.DicProperties.ContainsKey(xml_node_name)) {
                            property_to_assign = this.DicProperties[xml_node_name];
                        }
                        else if (property_to_assign == Item.LISTPRICE) {
                            if (inner_value == null)
                            {
                                inner_value = new ListPriceData();
                            }
                            inner_property_to_assign = (ListPriceData.GetPropertiesDictionary())[xml_node_name];
                        }
                        break;
                    
                    // Found close tag - </Element>
                    case XmlNodeType.EndElement:
                        xml_node_name = xml_reader.Name.ToLower();
                        if (this.DicProperties.ContainsKey(xml_node_name) && (property_to_assign == Item.LISTPRICE)) {
                            book.AssignProperty(property_to_assign, inner_value);
                            inner_value = null;
                            inner_property_to_assign = Item.INVALID;
                            property_to_assign = Item.INVALID;
                        }

                        break;
                    
                    // Found data between tags - <Element>Text</Element>
                    case XmlNodeType.Text:
                        if (inner_property_to_assign != Item.INVALID) {
                            switch (property_to_assign) { 
                                case Item.LISTPRICE:
                                    ((ListPriceData)inner_value).AssignProperty(inner_property_to_assign, xml_reader.Value);
                                    break;
                            }

                      }
                        else if (property_to_assign != Item.INVALID) {
                            book.AssignProperty(property_to_assign, xml_reader.Value);
                            property_to_assign = Item.INVALID;
                        }
                        break;

                    default:
                        break;
                }
            }

            return(lista_resultado);
        }
    }
}
